/**
 * Copyright 2019-2020 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include <memory>

#include "common/util/op_info_util.h"
#include "graph/ge_context.h"

#define private public
#define protected public
#include "ops_store/ops_kernel_manager.h"
#include "ops_store/sub_op_info_store.h"
#include "ops_store/op_kernel_info.h"
#include "graph/utils/graph_utils.h"
#include "graph/utils/op_desc_utils.h"
#include "graph/utils/attr_utils.h"
#include "adapter/common/op_store_adapter_manager.h"
#include "adapter/tbe_adapter/tbe_op_store_adapter.h"
#include "graph_optimizer/op_judge/imply_type/op_impl_type_judge.h"
#include "graph_optimizer/op_judge/format_and_dtype/op_format_dtype_judge.h"
#include "graph_optimizer/op_judge/format_and_dtype/strategy/matcher/dtype/op_dtype_rise_matcher.h"
#include "graph_optimizer/op_judge/format_and_dtype/strategy/matcher/format/op_format_matcher.h"
#include "graph_optimizer/shape_format_transfer/trans_node_manager/trans_node_manager.h"
#include "graph/debug/ge_attr_define.h"
#include "common/configuration.h"
using namespace std;
using namespace ge;
using namespace fe;
#define DIMENSION_4 (4)
#define DIMENSION_1 (1)
using OpImplTypeJudgePtr = std::shared_ptr<OpImplTypeJudge>;
using OpFormatDtypeJudgePtr = std::shared_ptr<OpFormatDtypeJudge>;
using OpDtypeRiseMatcherPtr = std::shared_ptr<OpDtypeRiseMatcher>;
using OpFormatMatcherPtr = std::shared_ptr<OpFormatMatcher>;
using OpFormatDtypeStrategyManagerPtr = std::shared_ptr<OpFormatDtypeStrategyManager>;
using TbeOpStoreAdapterPtr = std::shared_ptr<TbeOpStoreAdapter>;
using TransNodeManagerPtr = std::shared_ptr<TransNodeManager>;

class UTEST_fusion_engine_op_judge_precision_mode : public testing::Test
{
 protected:
  void SetUp()
  {
    op_store_adapter_manager_ptr_ = std::make_shared<OpStoreAdapterManager>();
    TbeOpStoreAdapterPtr tbe_adapter_ptr = std::make_shared<TbeOpStoreAdapter>();
    op_store_adapter_manager_ptr_->map_all_op_store_adapter_.emplace(std::make_pair("tbe_op_adapter", tbe_adapter_ptr));

    std::map<std::string, std::string> options;
    fe_ops_kernel_info_store_ptr_ = make_shared<fe::FEOpsKernelInfoStore>(op_store_adapter_manager_ptr_, fe::AI_CORE_NAME);
    FEOpsStoreInfo tbe_custom {
        6,
        "tbe-custom",
        EN_IMPL_HW_TBE,
        "./air/test/engines/nneng/ut/testcase/fusion_engine/ops_kernel_store/fe_config/tbe_custom_opinfo",
        "",
        false,
        false};
    vector<FEOpsStoreInfo> store_info;
    store_info.emplace_back(tbe_custom);
    Configuration::Instance(fe::AI_CORE_NAME).ops_store_info_vector_ = (store_info);
    OpsKernelManager::Instance(AI_CORE_NAME).Finalize();

    fe_ops_kernel_info_store_ptr_->Initialize(options);
    reflection_builder_ptr_ = std::make_shared<ge::RefRelations>();

    op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
    op_format_dtype_judge_ptr_->Initialize();

    OpsKernelManager::Instance(AI_CORE_NAME).Finalize();

    OpsKernelManager::Instance(AI_CORE_NAME).Initialize();

  }

  void TearDown()
  {

  }

  static void CreateUnknownShapeGraph(ComputeGraphPtr graph, ge::Format d_format, ge::Format format, ge::GeShape unknown_shape) {
    OpDescPtr g_op = std::make_shared<OpDesc>("Data", fe::DATA);
    OpDescPtr h_op = std::make_shared<OpDesc>("UnknownShape1", "UnknownShape");

    //add descriptor
    vector<int64_t> dim({4, 33, 12, 16, 16});
    GeShape shape(dim);
    GeTensorDesc tensor_desc(shape);
    tensor_desc.SetOriginFormat(FORMAT_NCHW);
    tensor_desc.SetFormat(d_format);
    tensor_desc.SetDataType(DT_FLOAT16);
    g_op->AddInputDesc("x", tensor_desc);
    g_op->AddOutputDesc("z", tensor_desc);
    ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
    ge::NodePtr g_node = graph->AddNode(g_op);

    GeTensorDesc tensor_desc_h(unknown_shape);
    tensor_desc_h.SetOriginFormat(format);
    tensor_desc_h.SetFormat(format);
    tensor_desc_h.SetDataType(DT_FLOAT16);
    h_op->AddInputDesc("x", tensor_desc_h);
    h_op->AddOutputDesc("z", tensor_desc_h);
    ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
    ge::NodePtr h_node = graph->AddNode(h_op);
    GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));
  }

  shared_ptr<fe::FEOpsKernelInfoStore> fe_ops_kernel_info_store_ptr_;
  OpStoreAdapterManagerPtr op_store_adapter_manager_ptr_;
  RefRelationsPtr reflection_builder_ptr_;
  OpFormatDtypeJudgePtr op_format_dtype_judge_ptr_;
};

TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_force_fp16)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = FORCE_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "G");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NHWC);
  tensor_desc_h.SetFormat(FORMAT_NHWC);
  tensor_desc_h.SetDataType(DT_INT8);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));
  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nhw_c_to_NC1_hw_c0({1, 1, 2, 3, 32});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nhw_c_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nhw_c_to_NC1_hw_c0);
}


TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_force_fp16_1)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = FORCE_FP16;
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("BM", "BatchMatMul");

  //add descriptor
  vector<int64_t> dim1({32, 1, 2});
  vector<int64_t> dim2({32, 2, 2});
  vector<int64_t> dim_o({32, 1, 2});
  GeShape shape1(dim1);
  GeShape shape2(dim2);
  GeTensorDesc tensor_desc1(shape1);
  tensor_desc1.SetOriginFormat(FORMAT_NHWC);
  tensor_desc1.SetFormat(FORMAT_NHWC);
  tensor_desc1.SetDataType(DT_FLOAT);
  tensor_desc1.SetOriginDataType(DT_FLOAT);

  GeTensorDesc tensor_desc2(shape2);
  tensor_desc2.SetOriginFormat(FORMAT_NHWC);
  tensor_desc2.SetFormat(FORMAT_NHWC);
  tensor_desc2.SetDataType(DT_FLOAT);
  tensor_desc2.SetOriginDataType(DT_FLOAT);

  g_op->AddInputDesc("x1", tensor_desc2);
  g_op->AddInputDesc("x2", tensor_desc2);
  g_op->AddOutputDesc("y", tensor_desc2);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);

  vector<int64_t> dim_result1({32, 1, 1, 16, 16});
  vector<int64_t> dim_result2({32, 1, 1, 16, 16});
  vector<int64_t> dim_result_o({32, 1, 1, 16, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_FRACTAL_NZ);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result1);

  EXPECT_EQ(g_op->GetInputDesc(1).GetFormat(), FORMAT_FRACTAL_NZ);
  EXPECT_EQ(g_op->GetInputDesc(1).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(1).GetShape().GetDims(), dim_result2);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_FRACTAL_NZ);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_o);
}

/* Original format is consecutive */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_force_fp16_2)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = FORCE_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "G");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT8);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 32});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}
/* Original format is consecutive */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_force_fp32_1)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = FORCE_FP32;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "G");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT16);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT8);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));


  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 32});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}
/* Original format is consecutive */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_force_fp32_2)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = FORCE_FP32;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G2");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "G2");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT16);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT32);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));


  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT64);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT64);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}

TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_auto_mixed_precision)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_MIX_PRECISION;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "G");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NHWC);
  tensor_desc_h.SetFormat(FORMAT_NHWC);
  tensor_desc_h.SetDataType(DT_INT8);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nhw_c_to_NC1_hw_c0({1, 1, 2, 3, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nhw_c_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nhw_c_to_NC1_hw_c0);
}

/* Original format is consecutive, Double can be the higher precision version
 * of float16 */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_auto_mixed_precision_2)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_MIX_PRECISION;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "GGray");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT16);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT32);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}

/* G2 is in Gray list, we can decrease the precision for it. */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_auto_mixed_precision_3)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_MIX_PRECISION;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "GGray");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_UINT8);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT32);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);

  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 2, 12, 16, 32});
  vector<int64_t> dim_h_NHWC({1, 3, 4, 2});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_UINT8);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_UINT8);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_h);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NHWC);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_h_NHWC);
}


/* G2 is in Black list, it must select the original dtype */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_auto_mixed_precision_4)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_MIX_PRECISION;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "GBlack");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_DOUBLE);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT32);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::FAILED);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT32);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_h);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT32);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_h);
}

/* G2 is in the white list and we must select fp16 if the original data type is
 * fp32/fp16. And select the original dtype in default mode when dtype is not
 * fp32 or fp16. */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_auto_mixed_precision_5)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_MIX_PRECISION;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "GWhite");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_DOUBLE);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT32);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::FAILED);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT32);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_h);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT32);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_h);
}

/* G2 is in the white list and we must select fp16 if the original data type is
 * fp32/fp16. And select the original dtype in default mode when dtype is not
 * fp32 or fp16. */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_auto_mixed_precision_6)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_MIX_PRECISION;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "GWhite");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_DOUBLE);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_FLOAT);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}

/* G(fp16) -> Cast(fp16 to fp32) -> G, if Cast is not in Black list,
 * we will jump over cast and select fp16 for the second G op. */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_auto_mixed_precision_7)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_MIX_PRECISION;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr cast_op = std::make_shared<OpDesc>("Cast", "Cast");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "GWhite");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT16);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_cast({4, 33, 12, 16});
  GeShape shape_cast(dim);
  GeTensorDesc tensor_desc_cast(shape_cast);
  tensor_desc_cast.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_cast.SetFormat(FORMAT_NCHW);
  tensor_desc_cast.SetDataType(DT_FLOAT);
  cast_op->AddInputDesc("x", tensor_desc); // Float 16
  cast_op->AddOutputDesc("z", tensor_desc_cast); // Float 32
  ge::AttrUtils::SetInt(cast_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr cast_node = graph->AddNode(cast_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_FLOAT);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), cast_node->GetInDataAnchor(0));
  GraphUtils::AddEdge(cast_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(cast_op->GetInputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(cast_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(cast_op->GetInputDesc(0).GetShape().GetDims(), dim_cast);

  EXPECT_EQ(cast_op->GetOutputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(cast_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(cast_op->GetOutputDesc(0).GetShape().GetDims(), dim_cast);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}

/* G(fp16) -> Cast(fp16 to fp32) -> G, if Cast is not in Black list,
 * we will jump over cast and select fp16 for the second G op. */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_auto_mixed_precision_8)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_MIX_PRECISION;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  /* Stub Cast in Black list */
  SubOpInfoStorePtr subOpInfoStorePtr = OpsKernelManager::Instance(AI_CORE_NAME).GetSubOpsKernelByStoreName("tbe-custom");
  OpKernelInfoPtr opKernelInfoPtr = subOpInfoStorePtr->GetOpKernelByOpType(fe::CAST);
  opKernelInfoPtr->op_store_info_.precision_policy = BLACK;
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr cast_op = std::make_shared<OpDesc>("Cast", fe::CAST);
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "GGray");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT16);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_cast({4, 33, 12, 16});
  GeShape shape_cast(dim);
  GeTensorDesc tensor_desc_cast(shape_cast);
  tensor_desc_cast.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_cast.SetFormat(FORMAT_NCHW);
  tensor_desc_cast.SetDataType(DT_FLOAT);
  cast_op->AddInputDesc("x", tensor_desc);
  cast_op->AddOutputDesc("z", tensor_desc_cast);
  ge::AttrUtils::SetInt(cast_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr cast_node = graph->AddNode(cast_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_FLOAT);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), cast_node->GetInDataAnchor(0));
  GraphUtils::AddEdge(cast_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  

  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(cast_op->GetInputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(cast_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(cast_op->GetInputDesc(0).GetShape().GetDims(), dim_cast);

  EXPECT_EQ(cast_op->GetOutputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(cast_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(cast_op->GetOutputDesc(0).GetShape().GetDims(), dim_cast);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
  /* restore Cast back to Gray list */
  opKernelInfoPtr->op_store_info_.precision_policy = BLACK;
}

/* Op GBlackOnlyFp16 is in blacklist but it does not support fp32 and it's original data type is fp32,
 * we return failed and tell the user this op should not be configured in black list. */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_auto_mixed_precision_9)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_MIX_PRECISION;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G", "GBlackOnlyFp16");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  

  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::FAILED);
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim);
}

TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_auto_mixed_precision_new)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = FORCE_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "G");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT);
  ge::AttrUtils::SetInt(tensor_desc, FORMAT_CONTINUOUS, 1);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NHWC);
  tensor_desc_h.SetFormat(FORMAT_NHWC);
  tensor_desc_h.SetDataType(DT_INT8);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nhw_c_to_NC1_hw_c0({1, 1, 2, 3, 32});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nhw_c_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nhw_c_to_NC1_hw_c0);
}

TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_default_mode)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = MUST_KEEP_ORIGIN_DTYPE;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "G");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT16);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NHWC);
  tensor_desc_h.SetFormat(FORMAT_NHWC);
  tensor_desc_h.SetDataType(DT_INT32);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::FAILED);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NHWC);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT32);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_h);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NHWC);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT32);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_h);
}

/* Original format is consecutive */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_default_mode_2)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = MUST_KEEP_ORIGIN_DTYPE;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "G");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT8);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 32});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}

/* When precisoin mode is must_keep_origin_dtype, we do
 * not allow precision reduce in CheckSupported. */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, check_support_with_must_keep_orignal_dtype)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = MUST_KEEP_ORIGIN_DTYPE;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "GBlackOnlyFp16");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  string reason;
  bool result = fe_ops_kernel_info_store_ptr_->CheckSupported(g_node->GetOpDesc(),  reason);
  ASSERT_EQ(result, false);
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim);
}

TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_allow_fp32_to_fp16)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_FP32_TO_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr h_op = std::make_shared<OpDesc>("G2", "G");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_DOUBLE);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NHWC);
  tensor_desc_h.SetFormat(FORMAT_NHWC);
  tensor_desc_h.SetDataType(DT_FLOAT16);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nhw_c_to_NC1_hw_c0({1, 1, 2, 3, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_DOUBLE);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nhw_c_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nhw_c_to_NC1_hw_c0);
}

/* Original format is consecutive */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_allow_fp32_to_fp16_2)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_FP32_TO_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("conv1", "ConvTemp");
  OpDescPtr h_op = std::make_shared<OpDesc>("conv2", "ConvTemp");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT8);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 32});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_INT8);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}


/* Original format is consecutive,
 * and the second op is GE op, it use mixed precision as default strategy. */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode,
       set_two_nodes_format_dtype_allow_fp32_to_fp16_3)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_FP32_TO_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("conv1", "ConvTemp");
  OpDescPtr h_op = std::make_shared<OpDesc>("conv2", "ConvTemp_Ge");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT16);
  g_op->AddInputDesc("x", tensor_desc);
  g_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_INT8);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));

  
  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 16});
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}

/* For pytorch, Data's format is FRACTAL_NZ. */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, pytorch_set_two_nodes_format_dtype_allow_fp32_to_fp16_2)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_FP32_TO_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr data_op = std::make_shared<OpDesc>("Data", fe::DATA);
  OpDescPtr h_op = std::make_shared<OpDesc>("bm", "BatchMatMul2");

  //add descriptor
  vector<int64_t> dim({4, 33, 2, 3, 16, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_FRACTAL_NZ);
  tensor_desc.SetDataType(DT_FLOAT);
  data_op->AddInputDesc("x", tensor_desc);
  data_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(data_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr data_node = graph->AddNode(data_op);

  vector<int64_t> dim_h({4, 33, 48, 32});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_FLOAT);
  h_op->AddInputDesc("x", tensor_desc_h);
  h_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(h_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(h_op);
  GraphUtils::AddEdge(data_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));
  
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret2, fe::SUCCESS);
  EXPECT_EQ(data_op->GetInputDesc(0).GetFormat(), FORMAT_FRACTAL_NZ);
  EXPECT_EQ(data_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(data_op->GetInputDesc(0).GetShape().GetDims(), dim);

  EXPECT_EQ(data_op->GetOutputDesc(0).GetFormat(), FORMAT_FRACTAL_NZ);
  EXPECT_EQ(data_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(data_op->GetOutputDesc(0).GetShape().GetDims(), dim);

  EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), FORMAT_FRACTAL_NZ);
  EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), dim);

  EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), FORMAT_FRACTAL_NZ);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), dim);
}

//TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_unknown_shape_c)
//{
//  map<ge::Format, vector<int64_t>> format_shape_map = {
//    {FORMAT_NCHW, {1, -1, 3, 4}},
//    {FORMAT_NHWC, {1, 2, 3, -1}},
//    {FORMAT_HWCN, {1, 2, -1, 4}},
//    {FORMAT_CHWN, {-1, 2, 3, 4}},
//    {FORMAT_NDHWC, {1, 2, 3, 4, -1}},
//    {FORMAT_DHWCN, {1, 2, 3, -1, 5}},
//    {FORMAT_DHWNC, {1, -1, 3, 4, -1}},
//  };
//  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_FP32_TO_FP16;
//  for (auto format_shape : format_shape_map) {
//    ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
//    GeShape shape_h(format_shape.second);
//    CreateUnknownShapeGraph(graph, FORMAT_NC1HWC0, format_shape.first, shape_h);
//
//    for (ge::NodePtr node : graph->GetDirectNode()) {
//      if (node->GetType() != "UnknownShape") {
//        continue;
//      }
//      
//      Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(node,  "tbe-custom");
//      ASSERT_EQ(ret2, fe::SUCCESS);
//      OpDescPtr h_op = node->GetOpDesc();
//      vector<int64_t> dim_result_nhw_c_to_NC1_hw_c0({1, 1, 2, 3, 16});
//      vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
//
//      EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), format_shape.first);
//      EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
//      EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), shape_h.GetDims());
//
//      EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), format_shape.first);
//      EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
//      EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), shape_h.GetDims());
//    }
//  }
//}

TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_two_nodes_format_dtype_unknown_shape_last_two)
{
  map<ge::Format, vector<int64_t>> format_shape_map = {
          {FORMAT_NCHW, {1, 2, -1, 4}},
          {FORMAT_NHWC, {1, 2, 3, -1}},
          {FORMAT_HWCN, {1, 2, -1, 4}},
          {FORMAT_CHWN, {1, 2, 3, -1}},
          {FORMAT_NDHWC, {1, 2, 3, 4, -1}},
          {FORMAT_DHWCN, {1, 2, 3, -1, 5}},
          {FORMAT_DHWNC, {1, -1, 3, 4, -1}},
  };
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = ALLOW_FP32_TO_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  for (auto format_shape : format_shape_map) {
    ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
    GeShape shape_h(format_shape.second);
    CreateUnknownShapeGraph(graph, FORMAT_FRACTAL_NZ, format_shape.first, shape_h);

    for (ge::NodePtr node : graph->GetDirectNode()) {
      if (node->GetType() != "UnknownShape") {
        continue;
      }
      
      Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(node,  "tbe-custom");
      ASSERT_EQ(ret2, fe::SUCCESS);
      OpDescPtr h_op = node->GetOpDesc();
      vector<int64_t> dim_result_nhw_c_to_NC1_hw_c0({1, 1, 2, 3, 16});
      vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});

      EXPECT_EQ(h_op->GetInputDesc(0).GetFormat(), format_shape.first);
      EXPECT_EQ(h_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
      EXPECT_EQ(h_op->GetInputDesc(0).GetShape().GetDims(), shape_h.GetDims());

      EXPECT_EQ(h_op->GetOutputDesc(0).GetFormat(), format_shape.first);
      EXPECT_EQ(h_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
      EXPECT_EQ(h_op->GetOutputDesc(0).GetShape().GetDims(), shape_h.GetDims());
    }
  }
}


/* Original format is consecutive */
TEST_F(UTEST_fusion_engine_op_judge_precision_mode, keep_dtype_01)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = FORCE_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g1_op = std::make_shared<OpDesc>("G1", "G");
  OpDescPtr g2_op = std::make_shared<OpDesc>("G2", "G");

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc tensor_desc(shape);
  tensor_desc.SetOriginFormat(FORMAT_NCHW);
  tensor_desc.SetFormat(FORMAT_NCHW);
  tensor_desc.SetDataType(DT_FLOAT);
  g1_op->AddInputDesc("x", tensor_desc);
  g1_op->AddOutputDesc("z", tensor_desc);
  ge::AttrUtils::SetInt(g1_op, FE_IMPLY_TYPE, 6);
  ge::AttrUtils::SetInt(g1_op, KEEP_DTYPE, 1);
  ge::NodePtr g_node = graph->AddNode(g1_op);


  vector<int64_t> dim_h({1, 2, 3, 4});
  GeShape shape_h(dim_h);
  GeTensorDesc tensor_desc_h(shape_h);
  tensor_desc_h.SetOriginFormat(FORMAT_NCHW);
  tensor_desc_h.SetFormat(FORMAT_NCHW);
  tensor_desc_h.SetDataType(DT_FLOAT);
  g2_op->AddInputDesc("x", tensor_desc_h);
  g2_op->AddOutputDesc("z", tensor_desc_h);
  ge::AttrUtils::SetInt(g2_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr h_node = graph->AddNode(g2_op);
  GraphUtils::AddEdge(g_node->GetOutDataAnchor(0), h_node->GetInDataAnchor(0));


  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  Status ret2 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(h_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  ASSERT_EQ(ret2, fe::SUCCESS);
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0({4, 3, 12, 16, 16});
  vector<int64_t> dim_result_nch_w_to_NC1_hw_c0_2({1, 1, 3, 4, 16});
  EXPECT_EQ(g1_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g1_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g1_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g1_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g1_op->GetOutputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g1_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0);

  EXPECT_EQ(g2_op->GetInputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g2_op->GetInputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g2_op->GetInputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);

  EXPECT_EQ(g2_op->GetOutputDesc(0).GetFormat(), FORMAT_NC1HWC0);
  EXPECT_EQ(g2_op->GetOutputDesc(0).GetDataType(), DT_FLOAT16);
  EXPECT_EQ(g2_op->GetOutputDesc(0).GetShape().GetDims(), dim_result_nch_w_to_NC1_hw_c0_2);
}

TEST_F(UTEST_fusion_engine_op_judge_precision_mode, set_cast_nodes_format_dtype_force_fp16)
{
  Configuration::Instance(fe::AI_CORE_NAME).precision_mode_ = FORCE_FP16;
  op_format_dtype_judge_ptr_ = std::make_shared<OpFormatDtypeJudge>(AI_CORE_NAME, op_store_adapter_manager_ptr_, reflection_builder_ptr_);
  op_format_dtype_judge_ptr_->Initialize();
  ComputeGraphPtr graph = std::make_shared<ComputeGraph>("test_graph_input");
  OpDescPtr g_op = std::make_shared<OpDesc>("Cast1", CAST);

  //add descriptor
  vector<int64_t> dim({4, 33, 12, 16});
  GeShape shape(dim);
  GeTensorDesc float_tensor_desc(shape);
  float_tensor_desc.SetOriginFormat(FORMAT_NCHW);
  float_tensor_desc.SetFormat(FORMAT_NCHW);
  float_tensor_desc.SetDataType(DT_FLOAT);
  g_op->AddInputDesc("x", float_tensor_desc);

  GeTensorDesc int16_tensor_desc(shape);
  int16_tensor_desc.SetOriginFormat(FORMAT_NCHW);
  int16_tensor_desc.SetFormat(FORMAT_NCHW);
  int16_tensor_desc.SetDataType(DT_INT16);

  g_op->AddOutputDesc("z", int16_tensor_desc);
  ge::AttrUtils::SetInt(g_op, FE_IMPLY_TYPE, 6);
  ge::NodePtr g_node = graph->AddNode(g_op);

  Status ret1 = op_format_dtype_judge_ptr_->SetDtypeAndFormatByPrecisionMode(g_node,  "tbe-custom");
  ASSERT_EQ(ret1, fe::SUCCESS);
  EXPECT_EQ(g_op->GetInputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(g_op->GetInputDesc(0).GetDataType(), DT_FLOAT);
  EXPECT_EQ(g_op->GetInputDesc(0).GetShape().GetDims(), dim);

  EXPECT_EQ(g_op->GetOutputDesc(0).GetFormat(), FORMAT_NCHW);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetDataType(), DT_INT16);
  EXPECT_EQ(g_op->GetOutputDesc(0).GetShape().GetDims(), dim);
}